/**
 * ZHU framework. Copyright 2012-, all rights reserved.
 *
 * $Id: AbstractPersistenceOperationService.java 16 2012-08-03 09:20:29Z zhuxiaopeng $
 * $Revision: 16 $
 * $Date: 2012-08-03 17:20:29 +0800 (五, 2012-08-03) $
 * $Author: zhuxiaopeng $
 */
package zhu.framework.service;

import javax.persistence.*;

import zhu.framework.entity.*;
import zhu.framework.entity.Entity;
import zhu.framework.entity.lifecycle.*;

/**
 * <p>
 * </p>
 * 
 * @author $Author: zhuxiaopeng $
 * @version $Revision: 16 $ - $Date: 2012-08-03 17:20:29 +0800 (五, 2012-08-03) $
 */
public abstract class AbstractPersistenceOperationService {

	protected <E extends Entity> E doCreateEntity(final E entity, final Class<E> entityClass) {
		final Lifecycle<E> lifecycle = getLifecycleFactory().getLifecycleFor(entityClass);
		return lifecycle.create(entity);
	}

	protected <E extends Entity> E doUpdateEntity(final E entity, final Class<E> entityClass) {
		final Lifecycle<E> lifecycle = getLifecycleFactory().getLifecycleFor(entityClass);
		return lifecycle.update(entity, null);
	}

	protected <E extends Entity> void doRemoveEntity(final E entity, final Class<E> entityClass) {
		final Lifecycle<E> lifecycle = getLifecycleFactory().getLifecycleFor(entityClass);
		lifecycle.remove(entity);
	}

	/**
	 * <p>
	 * プロパティ<code>lifecycleFactory</code>の値を取得する。
	 * </p>
	 * 
	 * @return プロパティ<code>lifecycleFactory</code>の値
	 */
	protected LifecycleFactory getLifecycleFactory() {
		if (lifecycleFactory == null) {
			lifecycleFactory = new LifecycleFactory(getEntityManager());
		}
		return lifecycleFactory;
	}

	/**
	 * <p>
	 * プロパティ<code>entityManager</code>の値を取得する。
	 * </p>
	 * 
	 * @return プロパティ<code>entityManager</code>の値
	 */
	private EntityManager getEntityManager() {
		return entityManager;
	}

	@PersistenceContext(name = PersistenceConstants.PERSISTENCE_UNIT_NAME, type = PersistenceContextType.TRANSACTION)
	private EntityManager entityManager;

	/**
	 * This is not a <code>final</code>, because this field must be initialized
	 * after entityManager is injected.
	 */
	private LifecycleFactory lifecycleFactory;
}
